package com.yiduo.outpost.core.web.exception;

import com.yiduo.outpost.core.model.exception.ErrorConstants;
import com.yiduo.outpost.core.model.exception.RestException;
import com.yiduo.outpost.core.model.result.ResultCodeEnum;
import jakarta.servlet.RequestDispatcher;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.web.error.ErrorAttributeOptions;
import org.springframework.boot.web.servlet.error.DefaultErrorAttributes;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.WebRequest;

import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;

/**
 * 微服务 - 异常拦截器
 */
@Slf4j
@AllArgsConstructor
public class WebMvcErrorAttributes extends DefaultErrorAttributes {

    private final MessageSource messageSource;

    @Override
    public Map<String, Object> getErrorAttributes(WebRequest webRequest, ErrorAttributeOptions options) {

        Map<String, Object> errorAttributes = new LinkedHashMap<>();
        Throwable error = getError(webRequest);
        log.error("异常信息：", error);
        // 默认异常返回业务状态码：50000
        errorAttributes.put(ErrorConstants.ERROR_RESPONSE_REQUEST_CODE, ResultCodeEnum.SYSTEM_ERROR.getCode());
        // 如果是参数异常
        Map<String, Object> stringObjectMap = ExceptionHandlerChain.determineErrorField(messageSource, error);
        if (Objects.nonNull(stringObjectMap)) {
            errorAttributes.putAll(stringObjectMap);
        }
        determineCode(errorAttributes, error);
        errorAttributes.put(ErrorConstants.ERROR_RESPONSE_MESSAGE, ExceptionHandlerChain.determineErrorMessage(messageSource, error));          // 提示信息
        errorAttributes.put(ErrorConstants.ERROR_RESPONSE_TIMESTAMP, new Date());
        errorAttributes.put(ErrorConstants.ERROR_RESPONSE_PATH, webRequest.getAttribute(RequestDispatcher.ERROR_REQUEST_URI, RequestAttributes.SCOPE_REQUEST));
        return errorAttributes;
    }

    private Map<String, Object> determineCode(Map<String, Object> errorAttributes, Throwable error) {
//        //sentinel 异常 状态码
//        if (BlockException.isBlockException(error)) {
//            errorAttributes.put(ErrorConstants.ERROR_RESPONSE_REQUEST_CODE, HttpStatus.TOO_MANY_REQUESTS.value());
//            String message = messageSource.getMessage(ErrorConstants.ERROR_SENTINEL_EXCEPTION, null, "被限流了", LocaleContextHolder.getLocale());
//            errorAttributes.put(ErrorConstants.ERROR_RESPONSE_MESSAGE,message);
//        }
        // 业务异常码
        if (error instanceof RestException) {
            RestException exception = (RestException) error;
            errorAttributes.put(ErrorConstants.ERROR_RESPONSE_REQUEST_CODE, exception.getCode());// 业务异常码
            errorAttributes.put(ErrorConstants.ERROR_RESPONSE_MESSAGE,messageSource.getMessage( exception.getMessage(), null, exception.getMessage(), LocaleContextHolder.getLocale()));
        }
        return errorAttributes;
    }

}
